package com.etone.smartAudit.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etone.smartAudit.domain.CertificateUploadFile;
import com.etone.smartAudit.mapper.CertificateUploadFileMapper;
import com.etone.smartAudit.vo.FileVO;
import com.etone.smartAudit.vo.bns.SetChainDTO;
import com.etone.smartAudit.vo.bns.SetChainVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class CertificateUploadFileServiceBak extends ServiceImpl<CertificateUploadFileMapper, CertificateUploadFile> {


    @Autowired
    private BSNService bsnService;

    @Value("${audit.filePath}")
    private String filePath;


    @Autowired
    private ThreadPoolTaskExecutor executor;

    /***
     * 保存文件
     * @param fileVOS 文件列表
     * @param id  相关联id
     * @param type 类型
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveFile(List<FileVO> fileVOS, Integer id, Integer type) {
        //查询已经存在的文件
        LambdaQueryWrapper<CertificateUploadFile> query = new LambdaQueryWrapper<>();
        query.eq(CertificateUploadFile::getRelativeId, id)
                .eq(CertificateUploadFile::getType, type);
        List<CertificateUploadFile> list = new ArrayList<>();
        this.remove(query);
        if (CollectionUtil.isNotEmpty(fileVOS)) {
            fileVOS.stream().forEach(fileVO -> {
                //查询文件是否存在
                String md5Id = bsnService.getFileMd5(filePath + fileVO.getPath());
                CertificateUploadFile file = new CertificateUploadFile();
                BeanUtils.copyProperties(fileVO, file);
                file.setType(type);
                file.setId(IdUtil.fastSimpleUUID());
                //此处使用异步获取区块上链hash值
//                    file.setHashKey(md5Id);
                file.setFileMd5(md5Id);
                file.setRelativeId(id);
                list.add(file);
            });
            this.saveBatch(list);
        }
        //sync hash
        handDnsHash(list);
    }

    /***
     * hand  dns  hash
     * @param list
     */
    private void handDnsHash(List<CertificateUploadFile> list) {
        try {
            list.stream().forEach(vo -> {
                executor.execute(() -> {
                    vo.setHashKey(getHash(vo.getFileMd5(), vo.getType()));
                    updateById(vo);
                    ThreadUtil.sleep(800);
                });
            });
        } catch (Exception e) {
            log.error("dns has fail");
        }
    }


    /***
     * 是否需要移除
     * @return
     */
    private boolean isRemoveFile(CertificateUploadFile file, List<FileVO> list) {

        return list.stream().anyMatch(vo -> StrUtil.isNotEmpty(vo.getUrl()) && vo.getUrl().equals(file.getUrl()) &&
                StrUtil.isNotEmpty(vo.getName()) && vo.getName().equals(file.getName())
                && StrUtil.isNotEmpty(vo.getOriginName()) && vo.getOriginName().equals(file.getOriginName()));
    }

    /***
     * 判断是否有包含存在的文件，不包含了则添加
     * @param file
     * @param realFiles
     * @return
     */
    private boolean hasFile(FileVO file, List<CertificateUploadFile> realFiles) {
        if (CollectionUtil.isEmpty(realFiles)) {
            return false;
        }
        return realFiles.stream().anyMatch(vo -> {

            return StrUtil.isNotEmpty(vo.getUrl()) && vo.getUrl().equals(file.getUrl()) &&
                    StrUtil.isNotEmpty(vo.getName()) && vo.getName().equals(file.getName())
                    && StrUtil.isNotEmpty(vo.getOriginName()) && vo.getOriginName().equals(file.getOriginName());
        });
    }

    private String getHash(String key, Integer type) {
        try {
            SetChainDTO dto = new SetChainDTO();
            dto.setHash(key);
            dto.setUid(key);
            dto.setContent("存证区块上链");
            SetChainVO vo = bsnService.fileSetChain(dto);
            return vo.getHash();
        } catch (Exception e) {
            log.error("上链失败", e);
        }
        return null;
    }
}
